package com.atnjupt.dao.impl;

import com.atnjupt.utils.JDBCUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * @author Wizarder
 * @create 2021-05-27 15:49
 */
public abstract class BaseDao<T> {
    private QueryRunner qr = new QueryRunner();
    private Class<T> type;
    {
        Type genericSuperclass = this.getClass().getGenericSuperclass();
        ParameterizedType pt = (ParameterizedType) genericSuperclass;
        Type[] actualTypeArguments = pt.getActualTypeArguments();
        type = (Class<T>) actualTypeArguments[0];
    }

    /**
     *
     * @param sql 执行的sql
     * @param args 填充sql占位符
     * @return 返回insert/update/delete影响的行数-1表示运行错误。
     */
    public int update(String sql,Object...args)  {
        /*int updateRow = 0;
        Connection connection = null;
        try {
            connection = JDBCUtils.getConnection();

            updateRow = qr.update(connection, sql, args);
            //为什么要两个return 因为try-catch是把异常处理了，相当于变成了正常代码，会继续执行try-catch后面的代码
            //比如上面两行代码中出现异常,那么就跳转到catch里处理异常了，这时候就不会走return updateRow。因此就会走finally后面的
            //语句所以需要return null;表示方法结束
            return updateRow;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JDBCUtils.close(connection);
        }
        return -1;*/
        Connection connection = JDBCUtils.getConnection();
        try {
            return qr.update(connection,sql,args);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            throw new RuntimeException(throwables);
        }

    }

    /**
     *查询返回一个 javaBean 的 sql 语句
     *@param sql   执行的sql
     * @param args  设置占位符
     * @return
     */
    public T queryForOne(String sql,Object...args){
//        T query = null;
//        Connection con = null;
//        try {
//             con =  JDBCUtils.getConnection();
//            query = qr.query(con, sql, new BeanHandler<T>(type), args);
//            return query;
//        } catch (SQLException e) {
//            e.printStackTrace();
//        } finally {
//            JDBCUtils.close(con);
//        }
//        return query;
        Connection connection = JDBCUtils.getConnection();
        try {
            return qr.query(connection,sql,new BeanHandler<T>(type),args);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            throw new RuntimeException(throwables);
        }
    }

    /**
     *查询返回多个 javaBean 的 sql 语句
     * @param sql   执行的sql
     * @param args  填充占位符
     * @return
     */
    public List<T> queryForList( String sql, Object...args) {
       /* List<T> query = null;
        Connection con = null;
        try {
            con = JDBCUtils.getConnection();
            query = qr.query(con, sql, new BeanListHandler<T>(type), args);
            return query;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JDBCUtils.close(con);
        }
        return null;*/
        Connection connection = JDBCUtils.getConnection();
        try {
            return qr.query(connection,sql,new BeanListHandler<T>(type),args);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            throw new RuntimeException(throwables);
        }
    }

    /**
     *查询分组函数的方法
     * @param sql 执行的sql
     * @param args 占位符
     * @return
     */
    public Object queryForSingleValue(String sql,Object...args)  {
      /*  Object query = null;
        Connection con = null;
        try {
            con = JDBCUtils.getConnection();
            query = qr.query(con, sql, new ScalarHandler(), args);
            return query;
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JDBCUtils.close(con);
        }
        return null;
    }*/
        Connection connection = JDBCUtils.getConnection();
        try {
            return qr.query(connection,sql,new ScalarHandler(),args);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            throw new RuntimeException(throwables);
        }
}
}
